<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Export\SurveyExport;
use App\Models\SurveyAnswer;
use App\Models\Survey;
use App\Models\SurveyProblem;
use App\Models\SurveyReply;
use App\Models\UserInfo;
use App\Models\UserWechatInfo;
use App\Validate\SurveyValidate;
use Illuminate\Support\Facades\DB;

/**
 * 问卷调查类
 * Class Survey
 * @package app\api\controller
 */
class SurveyController extends CommonController
{


    // 自动验证
    public $validate = null;
    public $surveyObj = null;
    public $surveyProblemObj = null;
    public $surveyAnswerObj = null;

    /**
     * 实例化问卷调查验证类
     * Survey constructor.
     */
    public function __construct()
    {
        parent::__construct();

        $this->validate = new SurveyValidate();
        $this->surveyObj = new Survey();
        $this->surveyProblemObj = new SurveyProblem();
        $this->surveyAnswerObj = new SurveyAnswer();
    }

    /**
     * 问卷调查列表
     * @param page 默认为 1
     * @param limit 限制条数 默认为 10
     * @param keywords 检索内容
     * @param is_play int 是否发布 1.发布 2.未发布    默认1
     */
    public function lists()
    {
        $page = intval($this->request->page) ?: 1;
        $limit = $this->request->limit ?: 10;
        $keywords = $this->request->keywords;
        $is_play = $this->request->is_play;

        // 获取数据
        $res = $this->surveyObj->select('id', 'survey_name', 'intro', 'start_time', 'end_time', 'is_play')
            ->where("is_del", 1)
            ->where(function ($query) use ($keywords) {
                if (!empty($keywords)) {
                    $query->where('survey_name', 'like', "%$keywords%");
                }
            })
            ->where(function ($query) use ($is_play) {
                if (!empty($is_play)) {
                    $query->where('is_play', $is_play);
                }
            })
            ->orderByDesc("id")
            ->paginate($limit)
            ->toArray();

        $res = $this->disPageData($res);
        foreach ($res['data'] as $key => $val) {
            if ($val['end_time'] < date('Y-m-d H:i:s')) {
                $res['data'][$key]['past_due'] = true; //已过期
            } else {
                $res['data'][$key]['past_due'] = false; //未过期
            }
            $res['data'][$key]['status'] = $this->surveyObj->getSurveyListStatus($val);
            $res['data'][$key]['intro'] = strip_tags($val['intro']);
            $res['data'][$key][$this->list_index_key] = $this->addSerialNumberOne($key, $page, $limit);
        }
        // 反馈数据
        if ($res['data']) {
            return $this->returnApi(200, "获取成功", true, $res);
        }
        return $this->returnApi(203, "暂无数据");
    }


    /**
     * 问卷调查详情
     * @param $id ：问卷调查id
     * @param keywords 检索内容
     */
    public function detail()
    {
        //增加验证场景进行验证
        if (!$this->validate->scene('detail')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }

        $keywords = $this->request->keywords;
        // 获取问卷调查是否存在
        $res = $this->surveyObj->select('id', 'survey_name', 'start_time', 'end_time', 'create_time', 'change_time', 'is_play', 'intro', 'reply_num')
            ->where("is_del", 1)
            ->find($this->request->id);

        if (empty($res)) {
            return $this->returnApi(203, "暂无数据");
        }

        // 获取所有问题
        $problem = $this->surveyProblemObj->select('id as pro_id', 'problem', 'type')
            ->where("sur_id", $this->request->id)
            ->where(function ($query) use ($keywords) {
                if (!empty($keywords)) {
                    $query->where('problem', 'like', "%$keywords%");
                }
            })
            ->orderBy("id")
            ->get()
            ->toArray();

        if (empty($problem)) {
            $res["problem"] = null;
            return $this->returnApi(200, "获取成功", true, $res);
        }

        // 获取该问卷所有答案
        $answer = $this->surveyAnswerObj->select('id as ans_id', 'answer', 'pro_id', 'reply_num')
            ->where("sur_id", $this->request->id)
            ->orderBy("id")
            ->get()
            ->toArray();
        // 追加问题入数据
        $res["problem"] = Survey::disSurveyData($problem, $answer, true, $res->reply_num);

        if ($res['end_time'] < date('Y-m-d H:i:s')) {
            $res['past_due'] = true; //已过期
        } else {
            $res['past_due'] = false; //未过期
        }

        return $this->returnApi(200, "获取成功", true, $res);
    }

    /**
     * 问卷调查答案显示 (老版，答案分别显示)
     * @param $id ：问卷调查id
     * @param keywords 检索内容
     */
    public function userReplyData()
    {
        //增加验证场景进行验证
        if (!$this->validate->scene('user_reply_data')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }
        $keywords = $this->request->keywords;
        // 获取问卷调查是否存在
        $res = $this->surveyObj->select('id', 'reply_num')->where("is_del", 1)->find($this->request->id);
        if (empty($res)) {
            return $this->returnApi(203, "暂无数据");
        }
        // 获取所有问题
        $problem = $this->surveyProblemObj->select('id as pro_id', 'problem', 'type')
            ->where("sur_id", $this->request->id)
            ->where(function ($query) use ($keywords) {
                if (!empty($keywords)) {
                    $query->where('problem', 'like', "%$keywords%");
                }
            })
            ->orderBy("id")
            ->get()
            ->toArray();
        if (empty($problem)) {
            return $this->returnApi(203, "暂无数据");
        }
        // 获取该问卷所有答案
        $answer = $this->surveyAnswerObj->select('id as ans_id', 'answer', 'pro_id', 'reply_num')
            ->where("sur_id", $this->request->id)
            ->orderBy("id")
            ->get()
            ->toArray();

        // 追加问题入数据
        $user_answer = Survey::disSurveyData($problem, $answer, true, $res->reply_num);
        return $this->returnApi(200, "获取成功", true, $user_answer);
    }


    /**
     * 问卷调查答案显示 (2.0版，按用户答案合并显示)
     * @param id string 问卷调查id
     * @param keywords 检索内容
     * @param page  页数 默认为 1
     * @param limit 每页条数 默认10
     */
    public function userReplyDataMerge()
    {
        //增加验证场景进行验证
        if (!$this->validate->scene('user_reply_merge_data')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }

        $limit = !empty($this->request->limit) ? $this->request->limit : 10;
        $page = !empty($this->request->page) ? $this->request->page : 1;
        $id = $this->request->id;
        $keywords = $this->request->keywords;

        // 获取问卷调查是否存在
        $res = $this->surveyObj->where("is_del", 1)->find($this->request->id);

        if (empty($res)) {
            return $this->returnApi(203, "暂无数据");
        }
        // 获取所有问题
        $problem = $this->surveyProblemObj->select('id', 'problem', 'type')
            ->where("sur_id", $this->request->id)
            ->where(function ($query) use ($keywords) {
                if (!empty($keywords)) {
                    $query->where('problem', 'like', "%$keywords%");
                }
            })
            ->orderBy("id")
            ->get()
            ->toArray();

        if (empty($problem)) {
            return $this->returnApi(203, "暂无数据");
        }
        // 获取所有问题
        $replyModel = new SurveyReply();
        $reply_data = $replyModel->getReplyList($id, $keywords);
        //设置表头
        $temp_row = [
            "id" => '序号',
            "nickname" => '用户昵称',
        ];

        foreach ($problem as $key => $val) {
            $type = $val['type'] == 1 ? '多选题' : ($val['type'] == 2 ? '单选题' : '填空题');
            $temp_row['problem_' . $val['id']] = '（' . ($type) . '）' . $val['problem'];
        }
        $temp_row['create_time'] = '回复时间';
        //执行导出
        $surveyExport = new SurveyExport();
        $return_data = $surveyExport->setData2($reply_data, $problem); //要导入的数据

        $data['temp_row'] = $temp_row;
        // 分页处理
        $page_data = array_chunk($return_data, $limit); //按条数分为一组
        // 获取当前页的数据
        $data['data'] = $page_data[$page - 1] ?? [];
        $data['total'] = count($return_data);
        $data['per_page'] = $limit;
        $data['current_page'] = $page;


        return $this->returnApi(200, "获取成功", true, $data);
    }


    /**
     * 添加调查问题
     * @param content json 格式数据 {"survey_name":"\u95ee\u5377\u6807\u9898","intro":"\u95ee\u5377\u7b80\u4ecb","start_time":"2020-04-22 10:10:00","end_time":"2020-04-28 10:10:00","problem":[{"title":"\u95ee\u53771","answer":["\u7b54\u68481","\u7b54\u68482","\u7b54\u68483"]},{"title":"\u95ee\u53772","answer":["\u7b54\u68481","\u7b54\u68482","\u7b54\u68483"]}]}
     * type 题目类型   1  多选  2 选择 （默认）3 填空题
     * answer_name 答案 选择题多选题都可以存在一个空选项（只能存在一个，存在多个，会自动过滤，且前台显示放在最后）、若 type 为 3 answer_name 必须为空）
     */
    public function add()
    {
        /*   $data = [
            'survey_name' => '问卷标题',
            'intro' => '问卷简介',
            'start_time' => '2020-04-22 10:10:00',
            'end_time' => '2020-04-28 10:10:00',
            'problem' => [
                [
                    'title' => '问卷1',
                    'type' => '1',
                    'answer' => [
                        [
                            'answer_name' => '答案一'
                        ],
                        [
                            'answer_name' => '其他(自定义)'
                        ]
                    ]
                ],
                [
                    'title' => '问卷2',
                    'type' => '2',
                    'answer' => [
                        [
                            'answer_name' => '答案一'
                        ],
                        [
                            'answer_name' => '其他(自定义)'
                        ]
                    ]
                ]
            ]
        ];
        echo json_encode($data);die; */

        $content = $this->request->content;
        if (empty($content)) return $this->returnApi(201, '参数错误');
        $content = json_decode($content, true);
        // dump($content);die;
        //增加验证场景进行验证
        if (!$this->validate->scene('add')->check($content)) {
            return $this->returnApi(201,  $this->validate->getError());
        }

        $is_exists = $this->surveyObj->nameIsExists($content['survey_name'], 'survey_name');

        if ($is_exists) {
            return $this->returnApi(202, "此问卷问题已存在，请重新添加");
        }


        DB::beginTransaction();
        try {
            //添加问卷
            $this->surveyObj->survey_name = $content['survey_name'];
            $this->surveyObj->intro =  addslashes($content['intro']);
            $this->surveyObj->start_time =  $content['start_time'];
            $this->surveyObj->end_time =  $content['end_time'];
            $this->surveyObj->save();

            $sur_id = $this->surveyObj->id; //问卷id

            foreach ($content['problem'] as $key => $val) {
                $title = $val['title'];
                $answer = $val['answer'];
                if (empty($title) || count($answer) < 1) {
                    throw new \Exception('请完整填写问卷问题');
                }
                //判断问题是否存在，已存在就不允许在次添加了
                $title_state = $this->surveyProblemObj->where('problem', $title)->where('sur_id', $sur_id)->first();
                if (!empty($title_state)) {
                    continue;
                }
                //新增问题
                $pro_id = $this->surveyProblemObj->insertProblem($sur_id, $title, $val);

                //判断答案是否唯一
                $answer_name = array_filter(array_unique(array_column($val['answer'], 'answer_name')));
                if (count($answer_name) != count(array_column($val['answer'], 'answer_name')) && count($answer_name) != count(array_column($val['answer'], 'answer_name')) - 1) {
                    throw new \Exception('[' . $title . ' ]此问题的答案有误, 请重新填写'); //可能是填空题，少一个答案
                }

                //新增答案
                $this->surveyAnswerObj->insertAnswer($answer, $sur_id, $pro_id, $val['type']);
            }
            DB::commit();
            return $this->returnApi(200, '添加成功', true);
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->returnApi(202, $e->getMessage());
        }
    }
    /**
     * 修改调查问题
     * @param content 内容
     * @param problem json 格式数据[{"title":"\u95ee\u53771","id":6,"answer":[{"conetnt":"\u7b54\u68481","state":1,"id":11},{"conetnt":"\u7b54\u68482","state":2,"id":12},{"conetnt":"\u7b54\u68483","state":1,"id":13}]},{"title":"\u95ee\u53772","id":7,"answer":[{"conetnt":"\u7b54\u68481","state":1,"id":14},{"conetnt":"\u7b54\u68482","state":12,"id":15},{"conetnt":"\u7b54\u68483","state":1,"id":16}]}]
     *     type 是否多选   1  多选  2 选择  3 填空题
     *
     *    big_delete_id 单独删除的大类id  多个 , 逗号拼接
     *    small_delete_id 单独删除的小类id 多个 , 逗号拼接
     *
     *    新增答案，新增无须 answer_id 参数，或为 0 或空，
     *    // 删除答案 只需传 answer_id  content可不传、 可为空, 既为删除
     *    新增问题，新增无须 pro_id 参数，或为 0 或空，
     *    // 删除问题 只需传pro_id  title可不传、 可为空, 既为删除
     */
    public function change()
    {
        /*  $data = [
            'survey_name' => '问卷标题',
            'intro' => '问卷简介',
            'start_time' => '2020-04-22 10:10:00',
            'end_time' => '2020-04-28 10:10:00',
            'sur_id' => 23,
            'big_delete_id' => 1,
            'small_delete_id' => 2,
            'problem' => [
                [
                    'title' => '问卷1',
                    'pro_id' => 1,
                    'type' => '1',
                    'answer' => [
                        ['answer_name'=>'答案1','answer_id'=>1],
                        ['answer_name'=>'答案2','answer_id'=>2],
                        ['answer_name'=>'答案3']
                    ]
                ],
                [
                    'title' => '问卷2',
                    'pro_id' => 2,
                    'type' => '2',
                    'answer' => [
                        ['answer_name'=>'答案1','answer_id'=>4],
                        ['answer_name'=>'答案2','answer_id'=>5],
                        ['answer_name'=>'答案3','answer_id'=>6]
                    ]
                ],
                [
                    'title' => '',
                    'pro_id' => 3,
                    'type' => '2',
                    'answer' => [
                        ['answer_name'=>'答案1','answer_id'=>4],
                        ['answer_name'=>'答案2','answer_id'=>5],
                        ['answer_name'=>'答案3','answer_id'=>6]
                    ]
                ]
            ]
        ];
        echo json_encode($data);die; */

        $content = $this->request->content;
        if (empty($content)) return $this->returnApi(201, '参数错误');
        $content = json_decode($content, true);
        //  dump($content);die;
        //增加验证场景进行验证
        if (!$this->validate->scene('change')->check($content)) {
            return $this->returnApi(201,  $this->validate->getError());
        }

        $sur_id = $content['sur_id']; //问卷id
        $surveyInfo = $this->surveyObj->where('is_del', 1)->find($sur_id);
        if (empty($surveyInfo)) {
            return $this->returnApi(202, '此问卷不存在');
        }

        if ($surveyInfo->is_play == 1) {
            return $this->returnApi(201, "请先撤销，在进行修改！");
        }

        if ($surveyInfo['reply_num'] !== 0) {
            return $this->returnApi(202, '此问卷已有人回答，禁止修改');
        }

        $is_exists = $this->surveyObj->nameIsExists($content['survey_name'], 'survey_name', $sur_id);
        if ($is_exists) {
            return $this->returnApi(202, "此问卷问题已存在，请重新修改");
        }

        DB::beginTransaction();
        try {
            //修改问卷
            $surveyInfo->survey_name = $content['survey_name'];
            $surveyInfo->intro =  addslashes($content['intro']);
            $surveyInfo->start_time =  $content['start_time'];
            $surveyInfo->end_time =  $content['end_time'];
            $surveyInfo->save();


            foreach ($content['problem'] as $key => $val) {
                $pro_id = $val['pro_id'];
                if (empty($pro_id)) {
                    //添加问题
                    $title = $val['title'];
                    //判断问题是否存在，已存在就不允许在次添加了
                    $title_state = $this->surveyProblemObj->where('problem', $title)->where('sur_id', $sur_id)->first();
                    if (!empty($title_state)) {
                        throw new \Exception('[' . $title . ' ]此问题已存在, 请重新填写');
                    }
                    //新增问题
                    $pro_id = $this->surveyProblemObj->insertProblem($sur_id, $title, $val);

                    //判断答案是否唯一
                    $answer_name = array_filter(array_unique(array_column($val['answer'], 'answer_name')));
                    if (count($answer_name) != count(array_column($val['answer'], 'answer_name'))) {
                        throw new \Exception('[' . $title . ' ]此问题的答案有误, 请重新填写');
                    }
                    //新增答案
                    $this->surveyAnswerObj->insertAnswer($val['answer'], $sur_id, $pro_id, $val['type']);
                } else {
                    //判断问题是否存在，已存在就不允许在次添加了
                    $title_state = $this->surveyProblemObj
                        ->where('problem', $val['title'])
                        ->where('id', '<>', $pro_id)
                        ->where('sur_id', $sur_id)
                        ->first();
                    if (!empty($title_state)) {
                        throw new \Exception('[' . $val['title'] . ' ]此问题已存在, 请重新填写');
                    } else {
                        $this->surveyProblemObj->where('id', $pro_id)->update([
                            'problem' => $val['title'],
                            'type' => $val['type'],
                            'change_time' => date('Y-m-d H:i:s'),
                        ]);
                    }
                }
                //修改答案
                $this->surveyAnswerObj->changeAnswer($val['answer'], $sur_id, $pro_id, $val['type']);
            }

            //删除大类id
            $big_delete_id = $content['big_delete_id'];

            if (!empty($big_delete_id)) {
                $big_delete_id = explode(',', $big_delete_id);
                $big_delete_id = array_filter(array_unique($big_delete_id));
                $this->surveyProblemObj->destroy($big_delete_id);
                //在删除所有的答案
                foreach ($big_delete_id as $k => $v) {
                    $this->surveyAnswerObj->where('pro_id', $v)->delete();
                }
            }
            //删除小类id
            $small_delete_id = $content['small_delete_id'];
            if (!empty($small_delete_id)) {
                $small_delete_id = explode(',', $small_delete_id);
                $small_delete_id = array_filter(array_unique($small_delete_id));
                $this->surveyAnswerObj->destroy($small_delete_id);
            }

            DB::commit();
            return $this->returnApi(200, '修改成功', true);
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->returnApi(202, $e->getMessage());
        }
    }

    /**
     * 问卷调查删除
     * @param sur_id      问卷id
     */
    public function del()
    {
        //增加验证场景进行验证
        if (!$this->validate->scene('del')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }


        $sur_id = $this->request->sur_id; //问卷id
        $surveyInfo = $this->surveyObj->find($sur_id);
        if (empty($surveyInfo)) {
            return $this->returnApi(202, '此问卷不存在');
        }
        if ($surveyInfo['is_play'] == 1) {
            return $this->returnApi(202, '此问卷已发布，禁止删除');
        }
        if ($surveyInfo['reply_num'] !== 0) {
            return $this->returnApi(202, '此问卷已有人回答，禁止删除');
        }

        $res = $surveyInfo->is_del = 2;
        $res = $surveyInfo->change_time = date('Y-m-d H:i:s');
        $res = $surveyInfo->save();
        if ($res) {
            return $this->returnApi(200, '删除成功', true);
        }
        return $this->returnApi(202, '删除失败');
    }

    /**
     * 问卷调查 撤销  与 发布
     * @param sur_id      问卷id
     * @param is_play   1 发布   2 撤销
     */
    public function cancelAndRelease()
    {
        //增加验证场景进行验证
        if (!$this->validate->scene('cancelAndRelease')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }


        $sur_id = $this->request->sur_id; //问卷id
        $is_play = $this->request->is_play; //问卷状态
        $surveyInfo = $this->surveyObj->where('is_del', 1)->find($sur_id);
        if (empty($surveyInfo)) {
            return $this->returnApi(202, '此问卷不存在');
        }
        if ($is_play == 1 && $surveyInfo->end_time < date('Y-m-d H:i:s')) {
            return $this->returnApi(202, '此问卷已过期，不允许发布');
        }

        $res = $surveyInfo->is_play = $is_play;
        $res = $surveyInfo->change_time = date('Y-m-d H:i:s');
        $res = $surveyInfo->save();

        if ($res) {
            return $this->returnApi(200, '操作成功', true);
        }
        return $this->returnApi(202, '操作失败');
    }
}
